package com.starsky.common.utils.easypoi;

import cn.afterturn.easypoi.word.WordExportUtil;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.apache.xmlbeans.XmlOptions;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.util.*;

/**
 * WordUtils
 *
 * @author ZENG.XIAO.YAN
 * @version 1.0
 */
public final class WordUtils {

    /**
     * word文件合并
     *
     * @param wordList
     * @return
     * @throws Exception
     */
    public static XWPFDocument mergeWord(List<XWPFDocument> wordList) throws Exception {
        if (CollectionUtils.isEmpty(wordList)) {
            throw new RuntimeException("待合并的word文档list为空");
        }
        XWPFDocument doc = wordList.get(0);
        int size = wordList.size();
        if (size > 1) {
            doc.createParagraph().setPageBreak(true);
            for (int i = 1; i < size; i++) {
                // 从第二个word开始合并
                XWPFDocument nextPageDoc = wordList.get(i);
                // 最后一页不需要设置分页符
                if (i != (size - 1)) {
                    nextPageDoc.createParagraph().setPageBreak(true);
                }
                appendBody(doc, nextPageDoc);
            }
        }
        return doc;
    }


    private static void appendBody(XWPFDocument src, XWPFDocument append) throws Exception {
        CTBody src1Body = src.getDocument().getBody();
        CTBody src2Body = append.getDocument().getBody();
        List<XWPFPictureData> allPictures = append.getAllPictures();
        // 记录图片合并前及合并后的ID
        Map<String, String> map = new HashMap<>();
        for (XWPFPictureData picture : allPictures) {
            String before = append.getRelationId(picture);
            //将原文档中的图片加入到目标文档中
            String after = src.addPictureData(picture.getData(), Document.PICTURE_TYPE_PNG);
            map.put(before, after);
        }
        appendBody(src1Body, src2Body, map);

    }

    private static void appendBody(CTBody src, CTBody append, Map<String, String> map) throws Exception {
        XmlOptions optionsOuter = new XmlOptions();
        optionsOuter.setSaveOuter();
        String appendString = append.xmlText(optionsOuter);
        String srcString = src.xmlText();
        String prefix = srcString.substring(0, srcString.indexOf(">") + 1);
        String mainPart = srcString.substring(srcString.indexOf(">") + 1, srcString.lastIndexOf("<"));
        String sufix = srcString.substring(srcString.lastIndexOf("<"));
        String addPart = appendString.substring(appendString.indexOf(">") + 1, appendString.lastIndexOf("<"));
        if (map != null && !map.isEmpty()) {
            //对xml字符串中图片ID进行替换
            for (Map.Entry<String, String> set : map.entrySet()) {
                addPart = addPart.replace(set.getKey(), set.getValue());
            }
        }
        //将两个文档的xml内容进行拼接
        CTBody makeBody = CTBody.Factory.parse(prefix + mainPart + addPart + sufix);
        src.set(makeBody);
    }


    /**
     * 测试导出
     */
    @Test
    public void exportWordTest() throws Exception {

        List<XWPFDocument> wordList = new ArrayList<>();
        // 1.通过easypoi生成word文档并放在集合里
        for (int i = 0; i < 10; i++) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("birthday", "birthday" + i);
            map.put("mobile", "mobile" + i);
            map.put("mother", "mother" + i);
            map.put("schoolName", "schoolName" + i);
            map.put("className", "className" + i);
            map.put("corpName", "corpName" + i);
            map.put("bactNo", "bactNo" + i);
            map.put("validity", "validity" + i);
            map.put("standard", "standard" + i);
            map.put("dosage", "dosage" + i);
            map.put("sex", "sex" + i);

            // 通过easyPoi生成word文档（即XWPFDocument）
            XWPFDocument doc = WordExportUtil.exportWord07("导出word.docx", map);
            wordList.add(doc);
        }
        // 2.把集合里面的word文档全部合并在一个文档
        XWPFDocument word = WordUtils.mergeWord(wordList);
        // 3.将合并后的word文档输出到文件
        FileOutputStream fos = new FileOutputStream(new File("导出word.docx"));
        word.write(fos);
        fos.close();
    }

}